// The main app module

/// <reference path="./typings/jquery/jquery.d.ts" />

// import UI widgets
import City = require("./UI/CityWidget");
import CmdLine = require("./UI/CommandLine");
import Edit = require("./UI/Editor");
import Dic = require("./UI/KarelDictionary");
import MsgBox = require("./UI/MessageBox");
import Img = require("./UI/ImageLibrary");
import Loc = require("./UI/Localization");

// import Karel's dictionary
import Dictionary = require("./MiddleLayer/Execution/Dictionary");

// import robot Karel
import Karel = require("./MiddleLayer/Execution/RobotKarel");

// disable AJAX caching
$.ajaxSetup({ cache: false });

// ambient declaration for shortcut library
declare var shortcut: any;

export class App {

    // references to the parts of the view
    private mCommandLine: CmdLine.CommandLine;
    private mEditor: Edit.Editor;
    private mDictionary: Dic.KarelDictionary;
    private mCity: City.CityWidget;
    private mLoaded: boolean;

    // constructor
    public constructor() {
        this.mLoaded = false;

        // init views
        this.mCity = new City.CityWidget();
        this.mCommandLine = new CmdLine.CommandLine(this.mCity.CityRenderer);
        this.mEditor = new Edit.Editor();
        this.mDictionary = new Dic.KarelDictionary();

        // set UI dependencies
        this.mDictionary.SetDependencies(this.mCommandLine, this.mEditor);
        this.mCity.SetDependencies(this.mCommandLine);
        this.mEditor.SetDependencies(this.mDictionary);
    }

    // runs the application
    public Run(): void {
        var that = this;

        // wait for document ready
        $(document).ready(function () {

            // register resizing event
            $(window).resize(function (event) {
                that.OnSizeChanged();
            });

            // register key-gesture handler for accelerators
            that.RegisterKeyGestures();

            // wait for loading all images
            Img.ImageLibrary.Instance.LoadImages(function () {
                Loc.Localization.Instance.Load(function () {
                    // mark app is loaded
                    that.mLoaded = true;
                    
                    // build layout page
                    that.LayoutPage();

                    // clean splash screen
                    $('#idLoading').fadeOut(1000);

                    // load the city if exists from the local storage
                    Karel.RobotKarel.Instance.Load();
                    that.mCity.CityRenderer.Render();
                    
                    // load commands from the localStorage if some are stored
                    Dictionary.Dictionary.Instance.Load();
                    that.mDictionary.RefreshCommands();

                    // check the supported browser
                    that.CheckSupportedBrowser();
                });
            });
        });
    }

    // handler for resolving accelarators
    private RegisterKeyGestures() {
        var that = this;

        // check Ctrl+N for the new command
        shortcut.add("Shift+N", function () {
            that.mEditor.NewCommand();
        });
        

        // check Ctrl+S for saving the current command
        shortcut.add("Ctrl+S", function () {
            that.mEditor.SaveCommand();
        });

        // check Ctrl+U for editing the current command
        shortcut.add("Shift+U", function () {
            that.mEditor.EditCurrentCommand();
        });

        // sets focus to the command line
        shortcut.add("Ctrl+Enter", function () {
            that.mCommandLine.FocusCommandLine();
        });

        // check cancelling the edit mode
        shortcut.add("Esc", function () {
            that.mEditor.CancelEditingCommand();
        });
    }

    // resize event handler
    private OnSizeChanged() {       
        app.LayoutPage();
    }

    // layouting the whole page when window resize is triggered
    private LayoutPage(): void {
        if (this.mLoaded == false)
            return;

        // layout the right pane
        var height = $("#rightPane").innerHeight();
        var commandLineHeight = 40;
        height = (height - commandLineHeight) / 2 - 1;

        $("#idDictionaryContainer").outerHeight(height);
        $("#idCommandLine").outerHeight(commandLineHeight);
        $("#idEditor").outerHeight(height);


        // layout child widgets
        this.mCity.LayoutControl();
        this.mDictionary.LayoutControl();
        this.mEditor.LayoutControl();
    }


    // check the supported browser and display warning
    private CheckSupportedBrowser() {
        // TO-DO: include modernizr.js
        // make a list of all HTML5 features
        // canvas
        // CSS calc
    }
}

// create and run the app object
var app = new App();
app.Run();
